package juc.blockqueue.delayqueue;

/**
 * @ClassName DelayedCache
 * @PackageName juc.blockqueue.delayqueue
 * @projectName myThread
 * @Description TODO
 * @Author games
 * @Date 2025/9/4 下午1:30
 * @Version 1.0
 */
import java.util.concurrent.*;

class CacheEntry implements Delayed {
    private final String key;
    private final String value;
    private final long expireTime;

    public CacheEntry(String key, String value, long ttlMillis) {
        this.key = key;
        this.value = value;
        this.expireTime = System.currentTimeMillis() + ttlMillis;
    }

    @Override
    public long getDelay(TimeUnit unit) {
        long diff = expireTime - System.currentTimeMillis();
        return unit.convert(diff, TimeUnit.MILLISECONDS);
    }

    @Override
    /**
     * 比较当前延迟对象与另一个延迟对象的过期时间
     * @param other 要比较的另一个延迟对象
     * @return 返回两个对象过期时间的比较结果：
     *         如果当前对象的过期时间小于other对象的过期时间，返回负数
     *         如果两个对象的过期时间相等，返回0
     *         如果当前对象的过期时间大于other对象的过期时间，返回正数
     */
    public int compareTo(Delayed other) {
        // 将other对象强制转换为CacheEntry类型，然后比较两个对象的expireTime属性
        return Long.compare(this.expireTime, ((CacheEntry) other).expireTime);
    }

    public String getKey() { return key; }
    public String getValue() { return value; }

    @Override
    public String toString() {
        return "CacheEntry{key='" + key + "', value='" + value + "'}";
    }
}

public class DelayedCache {
    private final DelayQueue<CacheEntry> expirationQueue = new DelayQueue<>();

    public void put(String key, String value, long ttlMillis) {
        CacheEntry entry = new CacheEntry(key, value, ttlMillis);
        expirationQueue.put(entry);
        System.out.println("Added to cache: " + entry);
    }

    public void startCleanupThread() {
        new Thread(() -> {
            try {
                while (true) {
                    CacheEntry expiredEntry = expirationQueue.take();
                    System.out.println("Expired and removed: " + expiredEntry);
                }
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }).start();
    }

    public static void main(String[] args) throws InterruptedException {
        DelayedCache cache = new DelayedCache();
        cache.startCleanupThread();

        cache.put("key1", "value1", 1000); // 1秒后过期
        cache.put("key2", "value2", 3000); // 3秒后过期
        cache.put("key3", "value3", 2000); // 2秒后过期

        Thread.sleep(5000); // 等待所有条目过期
    }
}

